/*
 * Copyright 2013 Agustina Martinez-Garcia

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package uk.da.dext.genxml;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import uk.da.dext.datastructs.MemoStruct;


public class MemoManagement implements ElementsManagement {
	private static final String FIELDS_SEPARATOR = ";";

	/**
	 * Fedora generated PID for the document referenced by this category set, just used once when creating the partial map
	 */
	private String currentDocumentPID;
	
	/**
	 * 
	 */
	private String currentDocumentXmlId;
	
	/**
	 * List of MemoStruct elements representing the memo elements from the spreadsheet
	 */
	private List<MemoStruct> memosList;
	
	/**
	 * Memos map from spreadsheet: pairs label/memo-text
	 */    
	private Map<String, String> memosMap;
	
	/**
	 * @param currentDocuementPID the currentDocuementPID to set
	 */
	public void setCurrentDocumentPID(String currentDocumentPID) {
		this.currentDocumentPID = currentDocumentPID;
	}
	/**
	 * @return the currentDocumentPID
	 */
	public String getCurrentDocumentPID() {
		return currentDocumentPID;
	}
	/**
	 * Sets the array of memos
	 * @param codesList
	 */
	public void setMemosList(List<MemoStruct> codesList) {
		this.memosList = codesList;
	}
	/**
	 * Gets the array of memos
	 * @return memosList
	 */
	public List<MemoStruct> getMemosList() {
		return memosList;
	}
	
	/**
	 * Constructor
	 */
	public MemoManagement() {
		this.memosList = new ArrayList<MemoStruct>();
		this.currentDocumentPID = "";
		this.currentDocumentXmlId = "";
		this.memosMap = new HashMap<String, String>();
	}

	/**
	 * Clears the list of memos
	 */
	public void clearList() {
		for (MemoStruct memo : this.memosList) {
			memo.clearMemoLists();
		}
		this.memosList.clear();
		this.memosMap.clear();
	}
	/**
	 * 
	 * @param memosSpreadsheet list of codes extracted from the QuDEx spreadsheet
	 */
	public void constructListOfElements(String language) {
		for (String memo : this.memosMap.keySet()) {
			processMemo(memo, this.memosMap.get(memo).toString(), language);
		}
		this.memosMap.clear();
	}
	/**
	 * 
	 * @param memoLabel
	 * @param memoText
	 * @param language
	 * @return
	 */
	private String processMemo(String memoLabel, String memoText, String language) {
		MemoStruct auxMemo = this.findElementByLabel(memoLabel);
		boolean isNewCode = false;
		
		if (auxMemo == null) {
			auxMemo = new MemoStruct();
			isNewCode = true;
			auxMemo.setMemoLabel(memoLabel);
			auxMemo.setMemoXmlId(QudexManagement.generateID());
			auxMemo.setMemoLanguage(language);
			auxMemo.setMemoText(memoText);
		}
		//Add current documentRef Fedora PID
		auxMemo.getDocumentRefs().add(this.currentDocumentPID);
		//Add generated XMLID for the Fedora PID
		auxMemo.getDocumentRefsXmlIds().add(this.currentDocumentXmlId);
		
		//New code not present
		if (isNewCode)
			this.memosList.add(auxMemo);
		return  "";
	}
	
		/**
	 * Finds a particular code in the array of codes by label value
	 * @param name display label of code to find
	 * @return code object if found, null otherwise
	 */
	public MemoStruct findElementByLabel(String name) {
		for (MemoStruct memo : this.memosList) {
			if (memo.getMemoLabel().equalsIgnoreCase(name)) {
				return memo;
			}
		}
		//New category to add
		return null;
	}
	/**
	 * Given a document Fedora Pid returns the generated XML-ID associated with it
	 * @param memoLabel current code display label
	 * @param documentPid fedora document pid to search for
	 * @return the document xml-id, null if not found
	 */
	public String getDocumentXmlId(String memoLabel, String documentPid) {
		
		MemoStruct auxMemo = this.findElementByLabel(memoLabel);
		int i = 0;
		if (auxMemo != null) {
			for (String document : auxMemo.getDocumentRefs()) {
				if (document.equalsIgnoreCase(documentPid)) {
					return auxMemo.getDocumentRefsXmlIds().get(i);
				}
				i++;
			}
			return null;
		} else return null;
	}
	/**
	 * 
	 * @param documentPid
	 * @return
	 */
	public String searchDocumentIds(String documentPid) {
		for (MemoStruct memo : this.memosList) {
			String documentXmlId = getDocumentXmlId(memo.getMemoLabel(), documentPid);
			if (documentXmlId != null)
				return documentXmlId;
		}
		return null;
	}
	/**
	 * @param currentDocumentXmlId the currentDocumentXmlId to set
	 */
	public void setCurrentDocumentXmlId(String currentDocumentXmlId) {
		this.currentDocumentXmlId = currentDocumentXmlId;
	}
	/**
	 * @return the currentDocumentXmlId
	 */
	public String getCurrentDocumentXmlId() {
		return currentDocumentXmlId;
	}
	public Object findElementByDisplayLabel(String name) {
	    for (MemoStruct memo : this.memosList) {
		if (memo.getMemoLabel().equalsIgnoreCase(name)) {
			return memo;
		}
	    }
	    //New category to add
	    return null;
	}
	public List<?> getElementsList() {
	    return this.memosList;
	}
	
	 /**
	     * Generates the list of CodeStruct instances from the data parsed in the
	     * spreadsheet
	     * 
	     * @param valueMemo
	     *            element in the spreadsheet labeled 'value_memo'
	     * @param labelMemo
	     *            element in the spreadsheet labeled 'label_memo'
	     * @return true if operation successful, false otherwise
	     */
	    public boolean generateElementsMap(String valueMemo, String labelMemo) {
		String[] arrayMemoText = valueMemo.split(FIELDS_SEPARATOR);
		String[] arrayMemoLabel = labelMemo.split(FIELDS_SEPARATOR);
		if (arrayMemoLabel.length != arrayMemoText.length)
		    return false;
		for (int i = 0; i < arrayMemoLabel.length; i++) {
		    this.memosMap.put(arrayMemoLabel[i], arrayMemoText[i]);
		}
		return true;

	    }
	public Map<?, ?> getElementsMap() {
	   return this.memosMap;
	}
	@SuppressWarnings("unchecked")
	public void setElementsMap(Map<?, ?> map) {
	   this.memosMap = (Map<String, String>) map;
	}
	@SuppressWarnings("unchecked")
	public void setElementsList(List<?> ellist) {
		this.setMemosList((List<MemoStruct>) ellist);
	}
}
